/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ssga.utils;

import java.util.*;
import java.sql.*;
import ssga.dataIO.DataIO;
import ssga.views.*;

/**
 * Clase estatica que guarda datos en forma estatica para almacenar 
 * en memoria datos provenientes de la base de datos y
 * minimizar asi los accesos via jdbc que debe hacer la 
 * aplicacion sobre datos que, en el corto plazo, se supone
 * que no cambian
 * Genera un repositorio al cual se accede por un nombre clave y dicho
 * nombre tiene asociado una lista de Entidades previamente cargadas
 * Trabajo bajo demanda: si la clave no existe, intentara hacer la consulta
 * sobre la base de datos, crear la clave en el repositorio y almacenar (asociado
 * a la misma) la lista de entidades resultante de la consulta
 * 
 * @author G. Cherencio
 * @version 1.6
 *
 * Clase que va a contener todas las listas que completaran los combos
 * de las aplicaciones. Se carga al iniciar la aplicacion
 */
public class DataCache {

    private static Map<String, List<EntidadView>> map = new HashMap<String, List<EntidadView>>();

    static { // cargo queries en cache que seran usando en distintas partes de la aplicacion
      
        getEntidades("spCarrera",
                "SELECT codigo,descr FROM SP_TBL_PLANE ORDER BY CODIGO ASC", new ViewPlane());
        
        getEntidades("spMateria",
           "SELECT codigom,descr FROM SP_TBL_MATERIA ORDER BY CODIGOM ASC",new ViewMateria());

//        getEntidades("spDocente",
//           "SELECT legajo,apenom FROM SP_TBL_MATERIA ORDER BY CODIGOM ASC",new ViewDocente());    

    }

    /**
     * Dada una clave que se supone previamente guardada en el repositorio
     * de cache, devuelvo el arreglo de entidades alamacenado
     * Si no existe clave, hago query a b.d. y cargo cache
     * 
     * @param  clave clave del repositorio a buscar / dar de alta
     * @param sql query a ejecutar en la b.d. para cargar cache en caso de que no estuviera cargado
     * @param sample objeto entidad de ejemplo que sirve para cargar lista de entidad, invocando al 
     *        metodo onLoad() de la interfase entidad
     * @return ArrayList de Entidades cargadas bajo dicha clave o bien un ArrayList vacio en caso de error
     */
    public static List<EntidadView> getEntidades(String clave, String sql, EntidadView sample) {
        if (map.containsKey(clave)) {
            return map.get(clave);
        }
        ResultSet rs = DataIO.getResultSet(sql);
        List<EntidadView> le = new ArrayList<EntidadView>();
        try {
            while (rs.next()) {
                sample.onLoad(le,rs); // se carga la capa model de la tabla
            }
            rs.close();
            map.put(clave, le);
            System.out.println("DataCache: cargue " + clave);
        } catch (SQLException sqle) {
            DataIO.doException(sqle, "DataCache Error loading objects from [" + sql + "]");
        }
        return le;
    }
    
     /**
     * Dada una clave que se supone previamente guardada en el repositorio
     * de cache, devuelvo el arreglo de entidades alamacenado
     * 
     * @param  clave clave del repositorio a buscar / dar de alta
     * @return ArrayList de Entidades cargadas o bien null si la clave no existe
     */
    public static List<EntidadView> getEntidades(String clave) {
        if ( map.containsKey(clave) ) return map.get(clave);
        return  null;
    }
    
     /**
     * Remuevo todo el cache, borro todo lo almacenado
     */
    public static void clear() {
        for ( List<EntidadView> le : map.values() ) {
            le.clear();
        }
        map.clear();      
    }
    /**
     * Remuevo clave del cache, borro todo lo almacenado en esa clave
     * @param clave clave a quitar del cache
     */
    public static void clear(String clave) {
        if ( map.containsKey(clave) ) {
            List<EntidadView> le = map.get(clave);
            le.clear();
            map.remove(clave);
        }
    }
}
